package com.zxtc.wh.utils;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * WebServlet提取参数的工具类
 * <p>
 * <p>
 * 上传参数有两种，一种是在GET请求的URL上附加参数键值对。
 * 另一种是在POST请求的请求体中添加参数键值对，
 * 参数大多数时候可以通过{@link ServletRequest#getParameter(String)}、{@link ServletRequest#getParameterMap()}、
 * {@link ServletRequest#getParameterValues(String)}等方式获取，然而如果使用POST请求上传文件和参数（from表单的属性enctype="multipart/form-data"），
 * 以上的方法就全部失效了，只能自行用io流读取用户上传的数据解析并使用，较为繁琐复杂，就有以简单方式提取参数的需求。
 * 本类就解决了这个需求，无论请求方式是GET还是POST，都可以简单的获取到上传的参数（文件）。
 */
public class WebServletParameterUtils {
    private final ServletFileUpload fileUpload;
    HttpServletRequest request;

    public WebServletParameterUtils(HttpServletRequest request) {
        this.fileUpload = FileUploadSaveUtil.getDefaultServletFileUpload();
        this.request = request;
    }

    public Object getParameter(String s) {
        Object parameter = null;
        List<FileItem> fileItems;
        try {
            fileItems = fileUpload.parseParameterMap(request).get(s);
            if (fileItems.size() >= 0) {
                parameter = fileItems.get(0);
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        return parameter;
    }

//    public Object[] getParameterValues(String s) {
//        return request.getParameterValues(s);
//    }

    /**
     * @param charsetName
     * @return
     */
    public Map<String, String[]> getParameterStringMap(String charsetName) {

        Map<String, String[]> map = new HashMap<>();

        try {
            Map<String, List<FileItem>> stringListMap = fileUpload.parseParameterMap(request);

            for (Map.Entry<String, List<FileItem>> entry : stringListMap.entrySet()) {
                map.put(entry.getKey(), (String[]) entry.getValue().parallelStream()
                        .filter(FileItem::isFormField)//过滤去除非属性的字段
                        .map(fileItem -> {
                            try {
                                return fileItem.getString(charsetName);
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                                return null;
                            }
                        })
                        .filter(Objects::nonNull)//过滤去除值为null的记录
                        .collect(Collectors.toList())
                        .toArray()
                );

            }

        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * @return
     */
    public Map<String, List<FileItem>> getParameterFileMap() {
        HashMap<String, List<FileItem>> map = new HashMap<>();

        try {
            fileUpload.parseParameterMap(request)
                    .entrySet()
                    .forEach(new Consumer<Map.Entry<String, List<FileItem>>>() {
                        @Override
                        public void accept(Map.Entry<String, List<FileItem>> entry) {

                            List<FileItem> list = entry.getValue()
                                    .stream()
                                    .filter(fileItem -> !fileItem.isFormField())
                                    .collect(Collectors.toList());
                            map.put(entry.getKey(), list);
                        }
                    });
            return map;
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        return map;

    }
}
